using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace sd
{
    public class SdModel
    {
        private readonly int dimension = 9;

        public SdPointModel[] Points
        {
            set;
            get;
        }

        public SdPointModel this[int index]
        {
            get
            {
                if (index > 80 || index < 1)
                    throw new IndexOutOfRangeException(nameof(index));

                return Points[index];
            }
        }

        public SdModel() { }
        public SdModel(IEnumerable<string> formatString)
        {
            if (formatString.Count() != 9)
                throw new Exception("初始化数据少于9行");

            int index = 0;
            Points = new SdPointModel[dimension * dimension];

            int y = 1;
            foreach (string line in formatString)
            {
                var lineDatas = line.Split("|");
                int x = 1;
                foreach (string number in lineDatas)
                {
                    Points[index] = new SdPointModel(x, y)
                    {
                        Value = string.IsNullOrEmpty(number.Trim()) ? 0 : Convert.ToInt32(number)
                    };
                    x++;
                    index++;
                }
                y++;
            }

            Console.WriteLine("数据初始化成功");
        }

        public void PrintToConsole(int step = 0)
        {
            if (step > 0)
                Console.WriteLine($"第{step}步为：");

            for (int i = 0; i < Points.Length; i++)
            {
                var point = Points[i];
                if (point.Step == step && step > 0)
                    Console.ForegroundColor = ConsoleColor.Green;
                else
                    Console.ForegroundColor = ConsoleColor.White;
                Console.Write($" {point.ToString()} ");

                Console.ForegroundColor = ConsoleColor.White;
                if (i > 0)
                {
                    if ((i + 1) % 9 == 0)
                        Console.WriteLine();
                    else if ((i + 1) % 3 == 0)
                    {
                        Console.ForegroundColor = ConsoleColor.Blue;
                        Console.Write("|");
                        Console.ForegroundColor = ConsoleColor.White;
                    }

                    if ((i + 1) % 27 == 0 && i != Points.Length - 1)
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("----------------------------");
                        Console.ForegroundColor = ConsoleColor.White;
                    }
                }
            }
        }
    }

    public class SdPointModel
    {
        public int Step { set; get; }

        public int X { set; get; }
        public int Y { set; get; }
        public int Value { set; get; }

        public int Part
        {
            get
            {
                var xpart = Math.Ceiling(Convert.ToDouble(X) / 3);
                var ypart = Math.Ceiling(Convert.ToDouble(Y) / 3) - 1;

                return Convert.ToInt32(ypart * 3 + xpart);
            }
        }

        private IEnumerable<int> enableNums = null;
        public IEnumerable<int> EnableNums
        {
            get
            {
                if (enableNums != null && GuessedNums != null)
                {
                    enableNums = enableNums.Except(GuessedNums);
                }
                return enableNums;
            }
            set
            {
                enableNums = value;
            }
        }

        public List<int> GuessedNums { set; get; }

        public SdPointModel() { }
        public SdPointModel(int x, int y)
        {
            X = x;
            Y = y;
            GuessedNums = new List<int>();
        }

        public override string ToString()
        {
            return Value == 0 ? "_" : Value.ToString();
        }
    }
}